From d18b5b7057fdd4a95455a7f74d9cbb7fe4dffccd Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 16 Feb 2006 19:04:33 +0100 Subject: [PATCH] Re-enable VGA acceleration under the new phys_to_machine_mapping. Signed-off-by: Yunhong Jiang Signed-off-by: Xin B Li Signed-off-by: Jun Nakajima --- tools/ioemu/hw/cirrus_vga.c | 35 ++++- tools/ioemu/hw/vga.c | 25 ++++ tools/ioemu/hw/vga_int.h | 1 + tools/ioemu/vl.c | 273 ++++++++++++++++++------------------ 4 files changed, 194 insertions(+), 140 deletions(-) diff --git a/tools/ioemu/hw/cirrus_vga.c b/tools/ioemu/hw/cirrus_vga.c index bcf9a56417..2786c3fae7 100644 --- a/tools/ioemu/hw/cirrus_vga.c +++ b/tools/ioemu/hw/cirrus_vga.c @@ -269,6 +269,7 @@ typedef struct CirrusVGAState { int last_hw_cursor_y_end; int real_vram_size; /* XXX: suppress that */ CPUWriteMemoryFunc **cirrus_linear_write; + int set_mapping; } CirrusVGAState; typedef struct PCICirrusVGAState { @@ -2431,7 +2432,6 @@ static void cirrus_linear_bitblt_writel(void *opaque, target_phys_addr_t addr, #endif } - static CPUReadMemoryFunc *cirrus_linear_bitblt_read[3] = { cirrus_linear_bitblt_readb, cirrus_linear_bitblt_readw, @@ -2448,9 +2448,9 @@ static CPUWriteMemoryFunc *cirrus_linear_bitblt_write[3] = { static void cirrus_update_memory_access(CirrusVGAState *s) { unsigned mode; + extern void * set_vram_mapping(unsigned long addr, unsigned long end); - extern void unset_vram_mapping(unsigned long addr, unsigned long end); - extern void set_vram_mapping(unsigned long addr, unsigned long end); + extern int unset_vram_mapping(unsigned long addr, unsigned long end); extern int vga_accelerate; if ((s->sr[0x17] & 0x44) == 0x44) { @@ -2466,15 +2466,36 @@ static void cirrus_update_memory_access(CirrusVGAState *s) mode = s->gr[0x05] & 0x7; if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) { - if (vga_accelerate && s->cirrus_lfb_addr && s->cirrus_lfb_end) - set_vram_mapping(s->cirrus_lfb_addr, s->cirrus_lfb_end); + if (vga_accelerate && s->cirrus_lfb_addr && s->cirrus_lfb_end) { + if (!s->set_mapping) { + void * vram_pointer; + s->set_mapping = 1; + vram_pointer = set_vram_mapping(s->cirrus_lfb_addr ,s->cirrus_lfb_end); + if (!vram_pointer){ + fprintf(stderr, "NULL vram_pointer\n"); + } else + { + vga_update_vram((VGAState *)s, vram_pointer, + VGA_RAM_SIZE); + } + } + } s->cirrus_linear_write[0] = cirrus_linear_mem_writeb; s->cirrus_linear_write[1] = cirrus_linear_mem_writew; s->cirrus_linear_write[2] = cirrus_linear_mem_writel; } else { generic_io: - if (vga_accelerate && s->cirrus_lfb_addr && s->cirrus_lfb_end) - unset_vram_mapping(s->cirrus_lfb_addr, s->cirrus_lfb_end); + if (vga_accelerate && s->cirrus_lfb_addr && s->cirrus_lfb_end) { + if(s->set_mapping) { + int error; + s->set_mapping = 0; + error = unset_vram_mapping(s->cirrus_lfb_addr, + s->cirrus_lfb_end); + if (!error) + vga_update_vram((VGAState *)s, NULL, VGA_RAM_SIZE); + } + } + s->cirrus_linear_write[0] = cirrus_linear_writeb; s->cirrus_linear_write[1] = cirrus_linear_writew; s->cirrus_linear_write[2] = cirrus_linear_writel; diff --git a/tools/ioemu/hw/vga.c b/tools/ioemu/hw/vga.c index bd4b72ac90..b74498456c 100644 --- a/tools/ioemu/hw/vga.c +++ b/tools/ioemu/hw/vga.c @@ -1974,6 +1974,31 @@ int vga_initialize(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base, return 0; } +int vga_update_vram(VGAState *s, void *vga_ram_base, int vga_ram_size) +{ + if (s->vram_size != vga_ram_size) + { + fprintf(stderr, "No support to change vga_ram_size\n"); + return -1; + } + + if ( !vga_ram_base ) + { + vga_ram_base = qemu_malloc(vga_ram_size); + if (!vga_ram_base) + { + fprintf(stderr, "reallocate error\n"); + return -1; + } + } + + /* XXX lock needed? */ + memcpy(vga_ram_base, s->vram_ptr, vga_ram_size); + s->vram_ptr = vga_ram_base; + + return 0; +} + /********************************************************/ /* vga screen dump */ diff --git a/tools/ioemu/hw/vga_int.h b/tools/ioemu/hw/vga_int.h index 316688265b..ca7ec373bc 100644 --- a/tools/ioemu/hw/vga_int.h +++ b/tools/ioemu/hw/vga_int.h @@ -164,5 +164,6 @@ void vga_draw_cursor_line_32(uint8_t *d1, const uint8_t *src1, unsigned int color0, unsigned int color1, unsigned int color_xor); +int vga_update_vram(VGAState *s, void *vga_ram_base, int vga_ram_size); extern const uint8_t sr_mask[8]; extern const uint8_t gr_mask[16]; diff --git a/tools/ioemu/vl.c b/tools/ioemu/vl.c index 618ddc0a31..6b32f286f0 100644 --- a/tools/ioemu/vl.c +++ b/tools/ioemu/vl.c @@ -2485,158 +2485,165 @@ get_vl2_table(unsigned long count, unsigned long start) #endif } -int -setup_mapping(int xc_handle, uint32_t dom, unsigned long toptab, - unsigned long *mem_page_array, unsigned long *page_table_array, - unsigned long v_start, unsigned long v_end) -{ - l1_pgentry_t *vl1tab=NULL, *vl1e=NULL; - l2_pgentry_t *vl2tab[4] = {NULL, NULL, NULL, NULL}; - l2_pgentry_t *vl2e=NULL, *vl2_table = NULL; - unsigned long l1tab; - unsigned long ppt_alloc = 0; - unsigned long count; - int i = 0; -#if _LEVEL_3_ - l3_pgentry_t *vl3tab = NULL; - unsigned long l2tab; - - if ( (vl3tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, - PROT_READ|PROT_WRITE, - toptab >> PAGE_SHIFT)) == NULL ) - goto error_out; - for (i = 0; i < 4 ; i++) { - l2tab = vl3tab[i] & PAGE_MASK; - vl2tab[i] = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, - PROT_READ|PROT_WRITE, - l2tab >> PAGE_SHIFT); - if(vl2tab[i] == NULL) - goto error_out; - } - munmap(vl3tab, PAGE_SIZE); - vl3tab = NULL; -#else - if ( (vl2tab[0] = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, - PROT_READ|PROT_WRITE, - toptab >> PAGE_SHIFT)) == NULL ) - goto error_out; -#endif +/* FIXME Flush the shadow page */ +static int unset_mm_mapping(int xc_handle, + uint32_t domid, + unsigned long nr_pages, + unsigned int address_bits, + unsigned long *extent_start) +{ + int err = 0; + xc_dominfo_t info; - for ( count = 0; count < ((v_end-v_start)>>PAGE_SHIFT); count++ ) - { - if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 ) - { - vl2_table = vl2tab[get_vl2_table(count, v_start)]; - vl2e = &vl2_table[l2_table_offset(v_start + - (count << PAGE_SHIFT))]; + err = xc_domain_memory_decrease_reservation(xc_handle, domid, + nr_pages, 0, extent_start); - l1tab = page_table_array[ppt_alloc++] << PAGE_SHIFT; - if ( vl1tab != NULL ) - munmap(vl1tab, PAGE_SIZE); + if ( err ) + fprintf(stderr, "Failed to decrease physmap\n"); - if ( (vl1tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, - PROT_READ|PROT_WRITE, - l1tab >> PAGE_SHIFT)) == NULL ) - { - goto error_out; - } - memset(vl1tab, 0, PAGE_SIZE); - vl1e = &vl1tab[l1_table_offset(v_start + (count<> PAGE_SHIFT)) == NULL ) - goto error_out; - for (i = 0; i < 4 ; i ++) { - l2tab = vl3tab[i] & PAGE_MASK; - vl2tab[i] = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, - PROT_READ|PROT_WRITE, - l2tab >> PAGE_SHIFT); - if (vl2tab[i] == NULL) - goto error_out; - } - munmap(vl3tab, PAGE_SIZE); - vl3tab = NULL; -#else - if ( (vl2tab[0] = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, - PROT_READ|PROT_WRITE, - toptab >> PAGE_SHIFT)) == NULL ) - goto error_out; -#endif + int i; + xc_dominfo_t info; + int err = 0; - for ( count = 0; count < ((v_end-v_start)>>PAGE_SHIFT); count++ ) { - if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 ) - { - vl2_table = vl2tab[get_vl2_table(count, v_start)]; - vl2e = &vl2_table[l2_table_offset(v_start + (count << PAGE_SHIFT))]; - l1tab = *vl2e & PAGE_MASK; - - if(l1tab == 0) - continue; - if ( vl1tab != NULL ) - munmap(vl1tab, PAGE_SIZE); - - if ( (vl1tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, - PROT_READ|PROT_WRITE, - l1tab >> PAGE_SHIFT)) == NULL ) - { - goto error_out; - } - vl1e = &vl1tab[l1_table_offset(v_start + (count<> PAGE_SHIFT; + + extent_start = malloc(sizeof(unsigned long) * nr_extents ); + if (extent_start == NULL) + { + fprintf(stderr, "Failed malloc on set_vram_mapping\n"); + return NULL; + } + + memset(extent_start, 0, sizeof(unsigned long) * nr_extents); + + for (i = 0; i < nr_extents; i++) + { + extent_start[i] = (begin + i * PAGE_SIZE) >> PAGE_SHIFT; + } + + set_mm_mapping(xc_handle, domid, nr_extents, 0, extent_start); + + if ( (vram_pointer = xc_map_foreign_batch(xc_handle, domid, + PROT_READ|PROT_WRITE, + extent_start, + nr_extents)) == NULL) + { + fprintf(logfile, + "xc_map_foreign_batch vgaram returned error %d\n", errno); + return NULL; + } + + memset(vram_pointer, 0, nr_extents * PAGE_SIZE); + + free(extent_start); + + return vram_pointer; } -void unset_vram_mapping(unsigned long addr, unsigned long end) +int unset_vram_mapping(unsigned long begin, unsigned long end) { - end = addr + VGA_RAM_SIZE; - /* FIXME Flush the shadow page */ - unsetup_mapping(xc_handle, domid, toptab, addr, end); + unsigned long * extent_start = NULL; + unsigned long nr_extents; + int i; + + /* align begin and end address */ + + end = begin + VGA_RAM_SIZE; + begin = begin & PAGE_MASK; + end = (end + PAGE_SIZE -1 ) & PAGE_MASK; + nr_extents = (end - begin) >> PAGE_SHIFT; + + extent_start = malloc(sizeof(unsigned long) * nr_extents ); + + if (extent_start == NULL) + { + fprintf(stderr, "Failed malloc on set_mm_mapping\n"); + return -1; + } + + memset(extent_start, 0, sizeof(unsigned long) * nr_extents); + + for (i = 0; i < nr_extents; i++) + extent_start[i] = (begin + (i * PAGE_SIZE)) >> PAGE_SHIFT; + + unset_mm_mapping(xc_handle, domid, nr_extents, 0, extent_start); + + free(extent_start); + + return 0; } + #elif defined(__ia64__) void set_vram_mapping(unsigned long addr, unsigned long end) {} void unset_vram_mapping(unsigned long addr, unsigned long end) {} -- 2.30.2